package com.docmgmt.mvp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.docmgmt.mvp.dto.AddFolderPermissionRequest;
import com.docmgmt.mvp.dto.FolderPermissionVO;
import com.docmgmt.mvp.dto.UpdateFolderPermissionRequest;
import com.docmgmt.mvp.entity.*;
import com.docmgmt.mvp.exception.BusinessException;
import com.docmgmt.mvp.exception.ForbiddenException;
import com.docmgmt.mvp.mapper.*;
import com.docmgmt.mvp.service.FolderPermissionService;
import com.docmgmt.mvp.service.PermissionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 文件夹权限表 服务实现类（v3.0 RBAC）
 * </p>
 *
 * @author Dora
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class FolderPermissionServiceImpl extends ServiceImpl<FolderPermissionMapper, FolderPermissionEntity> implements FolderPermissionService {

    private final FolderPermissionMapper folderPermissionMapper;
    private final FolderMapper folderMapper;
    private final UserMapper userMapper;
    private final DepartmentMapper departmentMapper;
    private final UserGroupMapper userGroupMapper;
    private final PermissionService permissionService;

    @Override
    public List<FolderPermissionVO> listFolderPermissions(Long folderId, Long userId) {
        log.info("查询文件夹权限列表: folderId={}, userId={}", folderId, userId);

        // 1. 检查文件夹是否存在
        FolderEntity folder = folderMapper.selectById(folderId);
        if (folder == null || folder.getIsDeleted()) {
            throw new BusinessException("文件夹不存在");
        }

        // 2. 权限检查：必须是文件夹所有者或有manage_permission权限
        if (!folder.getOwnerId().equals(userId) &&
            !permissionService.checkPermission(userId, "folder:" + folderId, "manage")) {
            throw new ForbiddenException("无权限查看文件夹权限列表");
        }

        // 3. 查询权限列表
        LambdaQueryWrapper<FolderPermissionEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FolderPermissionEntity::getFolderId, folderId)
               .orderByDesc(FolderPermissionEntity::getPriority)
               .orderByDesc(FolderPermissionEntity::getCreatedAt);

        List<FolderPermissionEntity> entities = folderPermissionMapper.selectList(wrapper);

        // 4. 转换为VO（需要填充subjectName）
        return entities.stream()
                .map(this::entityToVO)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FolderPermissionVO addFolderPermission(Long folderId, AddFolderPermissionRequest request, Long userId) {
        log.info("添加文件夹权限: folderId={}, subjectType={}, subjectId={}, permission={}, userId={}",
                folderId, request.getSubjectType(), request.getSubjectId(), request.getPermission(), userId);

        // 1. 检查文件夹是否存在
        FolderEntity folder = folderMapper.selectById(folderId);
        if (folder == null || folder.getIsDeleted()) {
            throw new BusinessException("文件夹不存在");
        }

        // 2. 权限检查：必须是文件夹所有者或有manage_permission权限
        if (!folder.getOwnerId().equals(userId) &&
            !permissionService.checkPermission(userId, "folder:" + folderId, "manage")) {
            throw new ForbiddenException("无权限管理文件夹权限");
        }

        // 3. 参数校验
        if (!"all".equals(request.getSubjectType()) && request.getSubjectId() == null) {
            throw new BusinessException("授权对象ID不能为空");
        }

        // 验证subjectId是否存在
        if (!validateSubject(request.getSubjectType(), request.getSubjectId())) {
            throw new BusinessException("授权对象不存在");
        }

        // 4. 检查是否已存在相同权限（防止重复）
        LambdaQueryWrapper<FolderPermissionEntity> existWrapper = new LambdaQueryWrapper<>();
        existWrapper.eq(FolderPermissionEntity::getFolderId, folderId)
                    .eq(FolderPermissionEntity::getSubjectType, request.getSubjectType());
        if (request.getSubjectId() != null) {
            existWrapper.eq(FolderPermissionEntity::getSubjectId, request.getSubjectId());
        }

        FolderPermissionEntity existing = folderPermissionMapper.selectOne(existWrapper);
        if (existing != null) {
            throw new BusinessException("该授权对象已存在权限，请使用更新接口");
        }

        // 5. 创建权限实体
        FolderPermissionEntity entity = new FolderPermissionEntity();
        entity.setFolderId(folderId);
        entity.setSubjectType(request.getSubjectType());
        entity.setSubjectId(request.getSubjectId());
        entity.setPermissionLevel(request.getPermission());

        // 根据权限级别设置细粒度权限
        setDetailedPermissions(entity, request.getPermission());

        entity.setIsInherited((byte) 0);  // 直接授权，非继承
        entity.setPriority(request.getPriority() != null ? request.getPriority() : 0);
        entity.setCreatedBy(userId);
        entity.setCreatedAt(LocalDateTime.now());
        entity.setUpdatedAt(LocalDateTime.now());

        // 6. 保存到数据库
        folderPermissionMapper.insert(entity);

        log.info("文件夹权限添加成功: permissionId={}", entity.getId());

        // 7. 返回VO
        return entityToVO(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FolderPermissionVO updateFolderPermission(Long folderId, Long permissionId, UpdateFolderPermissionRequest request, Long userId) {
        log.info("更新文件夹权限: folderId={}, permissionId={}, permission={}, userId={}",
                folderId, permissionId, request.getPermission(), userId);

        // 1. 检查文件夹是否存在
        FolderEntity folder = folderMapper.selectById(folderId);
        if (folder == null || folder.getIsDeleted()) {
            throw new BusinessException("文件夹不存在");
        }

        // 2. 权限检查
        if (!folder.getOwnerId().equals(userId) &&
            !permissionService.checkPermission(userId, "folder:" + folderId, "manage")) {
            throw new ForbiddenException("无权限管理文件夹权限");
        }

        // 3. 查询权限记录
        FolderPermissionEntity entity = folderPermissionMapper.selectById(permissionId);
        if (entity == null || !entity.getFolderId().equals(folderId)) {
            throw new BusinessException("权限记录不存在");
        }

        // 4. 更新权限
        entity.setPermissionLevel(request.getPermission());
        setDetailedPermissions(entity, request.getPermission());

        if (request.getPriority() != null) {
            entity.setPriority(request.getPriority());
        }

        entity.setUpdatedAt(LocalDateTime.now());

        folderPermissionMapper.updateById(entity);

        log.info("文件夹权限更新成功: permissionId={}", permissionId);

        return entityToVO(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteFolderPermission(Long folderId, Long permissionId, Long userId) {
        log.info("删除文件夹权限: folderId={}, permissionId={}, userId={}", folderId, permissionId, userId);

        // 1. 检查文件夹是否存在
        FolderEntity folder = folderMapper.selectById(folderId);
        if (folder == null || folder.getIsDeleted()) {
            throw new BusinessException("文件夹不存在");
        }

        // 2. 权限检查
        if (!folder.getOwnerId().equals(userId) &&
            !permissionService.checkPermission(userId, "folder:" + folderId, "manage")) {
            throw new ForbiddenException("无权限管理文件夹权限");
        }

        // 3. 查询权限记录
        FolderPermissionEntity entity = folderPermissionMapper.selectById(permissionId);
        if (entity == null || !entity.getFolderId().equals(folderId)) {
            throw new BusinessException("权限记录不存在");
        }

        // 4. 删除权限
        folderPermissionMapper.deleteById(permissionId);

        log.info("文件夹权限删除成功: permissionId={}", permissionId);
    }

    /**
     * 根据权限级别设置细粒度权限
     *
     * @param entity     权限实体
     * @param permission 权限级别（read/write/admin）
     */
    private void setDetailedPermissions(FolderPermissionEntity entity, String permission) {
        switch (permission.toLowerCase()) {
            case "read":
                entity.setCanRead((byte) 1);
                entity.setCanWrite((byte) 0);
                entity.setCanDelete((byte) 0);
                entity.setCanShare((byte) 0);
                entity.setCanManagePermission((byte) 0);
                break;
            case "write":
                entity.setCanRead((byte) 1);
                entity.setCanWrite((byte) 1);
                entity.setCanDelete((byte) 0);
                entity.setCanShare((byte) 1);
                entity.setCanManagePermission((byte) 0);
                break;
            case "admin":
                entity.setCanRead((byte) 1);
                entity.setCanWrite((byte) 1);
                entity.setCanDelete((byte) 1);
                entity.setCanShare((byte) 1);
                entity.setCanManagePermission((byte) 1);
                break;
            case "owner":
                // Owner级别权限（保留，暂不对外开放）
                entity.setCanRead((byte) 1);
                entity.setCanWrite((byte) 1);
                entity.setCanDelete((byte) 1);
                entity.setCanShare((byte) 1);
                entity.setCanManagePermission((byte) 1);
                break;
            default:
                throw new BusinessException("不支持的权限级别: " + permission);
        }
    }

    /**
     * 验证授权对象是否存在
     *
     * @param subjectType 对象类型
     * @param subjectId   对象ID
     * @return 是否存在
     */
    private boolean validateSubject(String subjectType, Long subjectId) {
        if ("all".equals(subjectType)) {
            return true;
        }

        if (subjectId == null) {
            return false;
        }

        switch (subjectType) {
            case "user":
                UserEntity user = userMapper.selectById(subjectId);
                return user != null;
            case "department":
                DepartmentEntity dept = departmentMapper.selectById(subjectId);
                return dept != null;
            case "user_group":
                UserGroupEntity group = userGroupMapper.selectById(subjectId);
                return group != null;
            default:
                return false;
        }
    }

    /**
     * 实体转VO
     *
     * @param entity 权限实体
     * @return 权限VO
     */
    private FolderPermissionVO entityToVO(FolderPermissionEntity entity) {
        String subjectName = getSubjectName(entity.getSubjectType(), entity.getSubjectId());

        return FolderPermissionVO.builder()
                .id(entity.getId())
                .folderId(entity.getFolderId())
                .subjectType(entity.getSubjectType())
                .subjectId(entity.getSubjectId())
                .subjectName(subjectName)
                .permission(entity.getPermissionLevel())
                .isInherited(entity.getIsInherited() == 1)
                .inheritFrom(null)  // TODO: 实现继承逻辑时填充
                .inheritFromPath(null)
                .canRead(entity.getCanRead() == 1)
                .canWrite(entity.getCanWrite() == 1)
                .canDelete(entity.getCanDelete() == 1)
                .canShare(entity.getCanShare() == 1)
                .canManagePermission(entity.getCanManagePermission() == 1)
                .priority(entity.getPriority())
                .createdBy(entity.getCreatedBy())
                .createdAt(entity.getCreatedAt())
                .build();
    }

    /**
     * 获取授权对象名称
     *
     * @param subjectType 对象类型
     * @param subjectId   对象ID
     * @return 对象名称
     */
    private String getSubjectName(String subjectType, Long subjectId) {
        if ("all".equals(subjectType)) {
            return "所有人";
        }

        if (subjectId == null) {
            return "未知";
        }

        try {
            switch (subjectType) {
                case "user":
                    UserEntity user = userMapper.selectById(subjectId);
                    return user != null ? user.getUsername() : "用户" + subjectId;
                case "department":
                    DepartmentEntity dept = departmentMapper.selectById(subjectId);
                    return dept != null ? dept.getName() : "部门" + subjectId;
                case "user_group":
                    UserGroupEntity group = userGroupMapper.selectById(subjectId);
                    return group != null ? group.getName() : "用户组" + subjectId;
                default:
                    return "未知对象";
            }
        } catch (Exception e) {
            log.warn("获取授权对象名称失败: subjectType={}, subjectId={}", subjectType, subjectId, e);
            return "未知";
        }
    }
}
